package com.gitee.wsl.struct.tree

import com.gitee.wsl.func.Consumer
import com.gitee.wsl.store.StoreServer
import com.gitee.wsl.struct.generator.CreateSeqByItem
import com.gitee.wsl.struct.generator.Seq
import com.gitee.wsl.struct.generator.SeqList
import com.gitee.wsl.struct.map.MapListNode
import com.gitee.wsl.struct.tree.bean.TreeItem
import com.gitee.wsl.struct.tree.bean.TreeNodeItem

object TreeHelper {

    class TreeNodeItemMap(saveStore: StoreServer, name: String) : MapListNode<TreeItem>(saveStore,name){

        override fun getSampleValue(): TreeItem {
            return createTreeNode(name)
        }

    }

    const val TREE_NODE_ROOT_NAME:String="TREE_NODE_ROOT_NAME_54651351654613"

    fun treeToMap(root: TreeNodeItem, nodeMap: MutableMap<String, TreeNodeItem> = mutableMapOf()){
        nodeMap[root.name] = root
        root.childNodes.forEach {
            treeToMap(it,nodeMap)
        }
    }

    fun createTreeNode(name: String=TREE_NODE_ROOT_NAME): TreeItem {
        return TreeItem(name)
    }

    fun findTreeNodeItem(tag:String,root: TreeNodeItem): TreeNodeItem?{
        if(root.name == tag)
            return root
        root.childNodes.forEach {
            if(it.name==tag)
                return it
            if(!it.isLeaf())
                return findTreeNodeItem(tag,it)
        }
        return null
    }


}


interface TreeSeq<T:Any,N:TreeNode>{

    // 递归函数
    fun <N> scanTree(c: Consumer<N>, node: N, seqCreate: CreateSeqByItem<N>) {
        c.accept(node)
        seqCreate.apply(node)?.consume { n ->
            scanTree(c, n, seqCreate)
        }
    }

    // 通用方法，可以遍历任何树
    fun <N> ofTree(node: N, sub: CreateSeqByItem<N>): Seq<N> {
        return Seq<N> { c -> scanTree(c, node, sub) }
    }

    // 遍历一个二叉树
    fun <N:Any> scanTree(node: N): Seq<N> {
        return ofTree(node) { subNode ->
             if (subNode is CategoryTreeNode) {
                return@ofTree SeqList.of(subNode.subtrees() as List<N>)
            }
            return@ofTree  null
        }
    }
}